/**   
 * @Title: BetterBeanUtils.java 
 * @Package com.betterjr.modules.workflow.snaker.util 
 * @Description: TODO(用一句话描述该文件做什么) 
 * @author licz
 * @date 2017年11月8日 上午8:40:47  
 */
package com.betterjr.modules.risk.loanmanage.util;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.BeanUtils;

import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.betterjr.common.exception.BytterException;
import com.betterjr.common.utils.BetterDateUtils;

public class BetterBeanUtils extends BeanUtils {
    final static Logger logger = LoggerFactory.getLogger(BetterBeanUtils.class);

    /** 
     * @Title: copyProperties2Bean 
     * @Description: 支持属性为List的拷贝 
     * @param dest 目标对象，标准的JavaBean 
     * @param orig 源对象，可为Map、标准的JavaBean 
     * @throws 
     * @author licz
     * @date 2017年12月25日 下午5:06:01 
     */
    @SuppressWarnings("rawtypes")
    public static void copyProperties2Bean(final Object dest, final Object orig) {
        try {
            if (orig instanceof Map) {
                final Iterator names = ((Map) orig).keySet().iterator();
                while (names.hasNext()) {
                    final String name = (String) names.next();
                    if (PropertyUtils.isWriteable(dest, name)) {
                        final Class type = PropertyUtils.getPropertyType(dest, name);
                        Object value = ((Map) orig).get(name);
                        if (value != null && !"".equals(value.toString())) {
                            if (Long.class.isAssignableFrom(type)) {
                                value = Long.parseLong(String.valueOf(value));
                            } else if (Integer.class.isAssignableFrom(type)) {
                                value = Integer.parseInt(String.valueOf(value));
                            } else if (List.class.isAssignableFrom(type) && value instanceof String) {
                                if (StringUtils.isNotBlank((String) value)) {
                                    final ObjectMapper mapper = new ObjectMapper();
                                    value = mapper.readValue(value.toString(), List.class);
                                } else {
                                    value = null;
                                }
                            } else if (Map.class.isAssignableFrom(type) && value instanceof String) {
                                if (StringUtils.isNotBlank((String) value)) {
                                    final ObjectMapper mapper = new ObjectMapper();
                                    value = mapper.readValue(value.toString(), Map.class);
                                } else {
                                    value = null;
                                }
                            } else if (Timestamp.class.isAssignableFrom(type)) {
                                Date tmpdate = BetterDateUtils.parseDate(value.toString());
                                if (tmpdate == null) {
                                    final SimpleDateFormat format = new SimpleDateFormat(
                                            BetterDateUtils.DATETIME_DEFFMT);
                                    tmpdate = format.parse(value.toString());
                                }
                                if (tmpdate != null) {
                                    value = new Timestamp(tmpdate.getTime());
                                } else {
                                    value = null;
                                }

                            } else if (BigDecimal.class.isAssignableFrom(type)) {
                                value = new BigDecimal(value.toString());
                            }
                            if (value != null) {
                                PropertyUtils.setSimpleProperty(dest, name, value);
                            }

                        }

                    }
                }
            } else {
                final java.lang.reflect.Field[] fields = orig.getClass().getDeclaredFields();
                for (int i = 0; i < fields.length; i++) {
                    final String name = fields[i].getName();
                    if (PropertyUtils.isReadable(orig, name) && PropertyUtils.isWriteable(dest, name)) {
                        final Object value = PropertyUtils.getSimpleProperty(orig, name);
                        if (value != null) {
                            PropertyUtils.setSimpleProperty(dest, name, value);
                        }
                    }
                }
            }
        }
        catch (final Exception e) {
            logger.error("BetterBeanUtils-copyProperties2Bean 执行失败！将源对象中的值覆盖到目标对象中，仅覆盖源对象中不为NULL值的属性", e);
            throw new BytterException("BetterBeanUtils-copyProperties2Bean 执行失败！将源对象中的值覆盖到目标对象中，仅覆盖源对象中不为NULL值的属性", e);
        }
    }

}
